package com.yang.controller;

import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.alipay.easysdk.factory.Factory;
import com.yang.config.AlipayConfig;
import com.yang.entity.AliPay;
import com.yang.entity.Cart;
import com.yang.entity.OrderDetail;
import com.yang.entity.Orders;
import com.yang.interceptors.LogExecutionTime;
import com.yang.mapper.OrderMapper;
import com.yang.service.Impl.OrderServiceImpl;
import com.yang.service.OrderService;
import com.yang.utils.ThreadLocalUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author
 * @Date Created in  2023/5/5 15:23
 * @DESCRIPTION:
 * @Version V1.0
 */
@RestController
@RequestMapping("/alipay")
@Transactional(rollbackFor = Exception.class)
public class AliPayController {

    @Resource
    private final AlipayConfig aliPayConfig = new AlipayConfig();

    @Resource
    private final OrderService orderService = new OrderServiceImpl();

    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "utf-8";
    private static final String SIGN_TYPE = "RSA2";

    /**
     * 支付宝支付接口
     *
     * @param httpResponse 响应
     * @throws Exception
     */
    @GetMapping("/pay") // 前端路径参数格式?subject=xxx&traceNo=xxx&totalAmount=xxx
    public void pay(
            AliPay aliPay,
            HttpServletResponse httpResponse
    ) throws Exception {
        // 创建Client，通过SDK提供的Client，负责调用支付宝的API接口
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        // 创建API对应的request，并设置参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        // 设置参数
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", aliPay.getTraceNo());
        bizContent.set("total_amount", aliPay.getTotalAmount());
        bizContent.set("subject", aliPay.getSubject());
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");
        // 添加参数
        request.setBizContent(bizContent.toString());
        request.setReturnUrl(aliPayConfig.getReturnUrl());
        // 输出查看
        String form = "";
        try {
            // 调用SDK生成表单
            form = alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        // 输出表单html到页面
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        // 直接将完整的表单html输出到页面
        httpResponse.getWriter().write(form);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @PostMapping("/notify")  // 注意这里必须是POST接口
    @LogExecutionTime
    public String payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
            }
            long orderId = Long.parseLong(params.get("out_trade_no"));
            long userId = orderService.getUserIdByOrderId(orderId);
            // 更新订单已支付的逻辑代码
            orderService.updateOrderStatus(2, orderId, userId);
        }

        return "success";
    }

}